import { computed, inject, onUnmounted, ref, watch } from 'vue';

const CMapRange = {
  name: 'CMapRange',
  inheritAttrs: false,
  props: {
    radius: undefined,
  },
  emits: ['change'],
  setup(props, { slots, emit }) {
    /* global BMapGL */

    let useMap = inject('useMap', () => {});
    let map = useMap();
    let circle = null;
    let center = ref(null);
    let radius = ref(null);
    let active = computed(() => {
      return radius.value && center.value && center.value.lng && center.value.lat;
    });

    watch(
      () => props.radius,
      (r) => {
        radius.value = Number.isFinite(r) && r > 0 ? r : 100;
        updateCircle();
      },
      { immediate: true }
    );

    function createCircle() {
      if (!circle) {
        circle = new BMapGL.Circle(center.value, radius.value, {
          fillOpacity: 0.25,
          fillColor: '#2E82FF',
          strokeColor: '#2E82FF',
          strokeWeight: 2,
          strokeOpacity: 0.75,
        });
      }
    }

    function updateCircle() {
      if (!circle) return;
      circle.setCenter(center.value);
      circle.setRadius(radius.value);
      map.addOverlay(circle);
      emit('change', { center: center.value, radius: radius.value });
      setViewport();
    }

    function setViewport() {
      if (!circle) return;
      let points = circle.points.reduce((res, item) => {
        if (item && item.latLng) res.push(item.latLng);
        return res;
      }, []);
      map.setViewport(points);
    }

    function onRightClick(e) {
      center.value = e.latlng;
      createCircle();
      updateCircle();
    }

    function close() {
      map.removeOverlay(circle);
      center.value = null;
      emit('change', { center: center.value, radius: radius.value });
    }

    map.addEventListener('rightclick', onRightClick);

    onUnmounted(() => {
      map.clearOverlays();
      map.removeEventListener('rightclick', onRightClick);
    });

    return () => {
      if (typeof slots.default !== 'function') {
        return null;
      }
      return slots.default({
        active: active.value,
        center: center.value,
        radius: radius.value,
        close: close,
      });
    };
  },
};

export default CMapRange;
